#include <iostream>
#include <vector>
#include <mutex>
#include <thread>
#include <functional>
#include <unordered_map>
#include <string>
#include <algorithm>
#include <cstring>
#include <utility>
#include <memory>
#include<mutex>
#include<thread>
#include<chrono>
#include <mutex>             
#include <condition_variable>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <stdio.h>
#include <assert.h>
#include<pthread.h>
#include<signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/timerfd.h>

// 日志宏编写
#define ERR 2
#define DEBUG 1
#define INF 0
#define LOG_LEVEL ERR


//strftime转换成年月日时分秒格式
#define LogPrintf(level, format, ...)                                                              \
    do                                                                                             \
    {                                                                                              \
        if (level <LOG_LEVEL)                                                                     \
            break;                                                                                 \
        time_t now = time(NULL);                                                                   \
        struct tm *local = localtime(&now);                                                        \
        char timeString[80];                                                                       \
        strftime(timeString, 79, "%Y-%m-%d %H:%M:%S", local);                                      \
        fprintf(stdout, "[%p %s %s:%d] " format "\n",(void*)pthread_self(), timeString, __FILE__, __LINE__, ##__VA_ARGS__); \
    } while (0)

// //format两侧要留出空格

#define INF_LOG(format, ...) LogPrintf(INF, format, ##__VA_ARGS__)
#define DEBUG_LOG(format, ...) LogPrintf(DEBUG, format, ##__VA_ARGS__)
#define ERR_LOG(format, ...) LogPrintf(ERR, format, ##__VA_ARGS__)

// 缓冲区模块
#define BUFFER_DEFAULT_SIZE 1024
class Buffer
{
private:
    std::vector<char> _buffer;
    uint64_t _read_index;  // 读偏移
    uint64_t _write_index; // 写偏移
public:
    Buffer(int capacity = BUFFER_DEFAULT_SIZE) : _buffer(capacity), _read_index(0), _write_index(0)
    {}
    ~Buffer() {}

    // 起始地址
    char *Begin()
    {
        return &_buffer[0];
        // return &*_buffer.begin()；*_buffer.begin等同于_buffer[0]
    }

    // 获取当前写位置
    char *WritePosition()
    {
        return Begin() + _write_index;
    }

    // 获取前沿空闲空间大小
    uint64_t HeadIdleSize()
    {
        return _read_index;
    }

    // 获取后沿空闲空间大小
    uint64_t TailIdleSize()
    {
        return _buffer.size() - _write_index;
    }

    // 移动数据到最前面
    void movBuffer()
    {
        uint64_t index = 0;
        while (_write_index > _read_index)
        {
            _buffer[index++] = _buffer[_read_index++];
        }
        _read_index = 0;
        _write_index = index;
    }

    // 确保可写空间足够（移动+扩容）
    bool EnsureWriteSpace(int len)
    {
        if (TailIdleSize() >= len)
        {
            return true;
        }
        else if (HeadIdleSize() + TailIdleSize() >= len)
        { // 移动数据
            movBuffer();
            return true;
        }
        else
        { // 扩容
            // 如果小于_buffer的数组大小会缩容
            _buffer.resize(_write_index + len);
            return true;
        }
    }

    // 将写位置向后移动指定位置
    void MoveWriteOffset(uint64_t len)
    {
        _write_index += len;
    }

    // 获取当前读位置
    char *ReadPosition()
    {
        return Begin() + _read_index;
    }

    // 获取可读数据大小
    uint64_t ReadAbleSize()
    {
        return _write_index - _read_index;
    }

    // 将读位置向后移动指定位置
    void MoveReadOffset(uint64_t len)
    {
        _read_index += len;
    }

    // 写入数据
    void Write(const void *date, uint64_t len)
    {
        if(len==0){
            return;
        }
        //确保有足够的可写空间
        EnsureWriteSpace(len);
        //在可写位置之后写入固定长度的数据
        std::copy((char *)date, ((char *)date) + len, WritePosition());
    }

    // 将写入数据操作和移动_write_index操作合二为一
    void WriteAndPush(const void *date, uint64_t len)
    {
        Write(date, len);
        MoveWriteOffset(len);
    }

    
    void WriteString(const std::string &data)
    {
        Write(data.c_str(), data.size());
    }

    void WriteStringAndPush(const std::string &data)
    {
        WriteString(data);
        MoveWriteOffset(data.size());
    }

    // 当你有一个const引用或指针时，你保证不会修改通过这个引用或指针访问的对象。
    // 如果允许调用非const成员函数，那么这些函数可能会修改对象的状态，
    // 从而违反了const引用的初衷。
    // 成员函数和const
    // 非const成员函数：这些函数可以修改对象的成员变量，
    // 因此它们不能在const对象或const引用/指针上被调用。
    // const成员函数：这些函数保证不会修改对象的任何成员变量（除了那些被标记为mutable的）。因此，它们可以在const对象或const引用/指针上被安全地调用。
    void WriteBuffer(Buffer &buffer)
    {
        Write(buffer.ReadPosition(), buffer.ReadAbleSize());
    }

    void WriteBufferAndPush(Buffer &buffer)
    {
        WriteBuffer(buffer);
        MoveWriteOffset(buffer.ReadAbleSize());
    }

    // 读取数据
    void Read(void *buf, uint64_t len)
    {
        if (ReadAbleSize() >= len)
        {
            std::copy(ReadPosition(), ReadPosition() + len, (char *)buf); // 保证参数类型统一
        }
        else
        {
            printf("缓冲区中的数据小于%lld", len);
        }
    }

    // 将读取数据操作和移动_read_index操作合二为一
    void ReadAndPop(void *buf, uint64_t len)
    {
        Read(buf, len);
        MoveReadOffset(len);
    }

    std::string ReadAsString(uint64_t len)
    {
        std::string s;
        // 要先扩容
        s.resize(len);
        // Read((char*)s.c_str(),len);这样强转是非常不严谨的
        Read(&s[0], len);
        return s;
    }

    // 将读取数据操作和移动_read_index操作合二为一
    std::string ReadAsStringAndPop(uint64_t len)
    {
        std::string re = ReadAsString(len);
        MoveReadOffset(len);
        return re;
    }

    // CRLF换行
    char *FindCRLF()
    {
        // 也可以使用menchr()查找
        int index = _read_index;
        while (index < _write_index)
        {
            if (_buffer[index] == '\n')
            {
                return &_buffer[index];
            }
            index++;
        }
        // 如果没有读取到换行也不需要返回，因为这是一个不完整的请求
        return nullptr;
    }

    // 读取一行数据
    std::string GetLine()
    {
        //得到\n的位置
        char *pos = FindCRLF();
        if(pos==nullptr){
            return "";
        }
        uint64_t len = pos - ReadPosition();
        // 只读len的话\n没有读进去
        return ReadAsString(len + 1);
    }

    std::string GetLineAndPop(){
        std::string str=GetLine();
        MoveReadOffset(str.size());
        return str;
    }

    // 清理功能
    // 不需要使用_buffer.clear(),直接归零覆盖写
    void Clear()
    {
        _write_index = 0;
        _read_index = 0;
    }
};

// 套接字管理模块
class Socket
{
private:
    int _sockfd;
public:
    Socket(int fd = -1) : _sockfd(fd) {}
    ~Socket() {}

    int Fd(){ return _sockfd;}
    // 创建套接字
    bool CreateSocket()
    {
        _sockfd = socket(AF_INET, SOCK_STREAM, 0);

        if(_sockfd<0){
            return false;
        }

        return true;
    }

    // 绑定地址信息
    bool Bind(uint32_t port)
    {
        struct sockaddr_in sockin;
        sockin.sin_family = AF_INET;
        sockin.sin_addr.s_addr =INADDR_ANY;
        sockin.sin_port = htons(port);
        socklen_t socklen = sizeof(sockin);
        if(bind(_sockfd, (struct sockaddr *)&sockin, socklen)<0){
            return false;
        }
        return true;
    }

    // 开始监听
    bool Listen(int n)
    {
        if(listen(_sockfd, n)<0){
            return false;
        }
        return true;

    }

    // 向服务器发起连接
    bool Connect(uint32_t port, std::string ip)
    {
        struct sockaddr_in sockin;
        sockin.sin_family = AF_INET;
        sockin.sin_addr.s_addr = inet_addr(ip.c_str());
        sockin.sin_port = htons(port);
        socklen_t socklen = sizeof(sockin);
        int newfd = connect(_sockfd, (struct sockaddr *)&sockin, socklen);
        if (newfd<0)
        {
            perror("connect");
            return false;
        }
        return true;
    }

    // 获取新连接
    int Accept()
    {
        struct sockaddr_in client;
        socklen_t clientlen;
        int newfd = accept(_sockfd, (struct sockaddr *)&client, &clientlen);
        if (newfd<0)
        {
            perror("connect");
            return -1;   
        }
        return newfd;
    }

    // 接收数据
    ssize_t Recv(void*buffer, int n,int flag=0)
    {
        int sz = recv(_sockfd, buffer, n, flag);
        //DEBUG_LOG("RECV sz:%d",sz);
        //返回大于0的值：表示成功接收到的字节数。
        // 返回0：这通常表示远端已经关闭了连接（正常关闭），即对方调用了 close() 或类似的函数来关闭套接字。在这种情况下，本地端也应该关闭套接字，并准备清理资源或采取其他适当的措施。
        // 返回-1：这表示发生了错误。
        if (sz <=0)
        {
            if (errno == EAGAIN || errno == EINTR) {
                return 0;
            }
            DEBUG_LOG("RECV FAILED:%s!!",strerror(errno));
            return -1;
        }
        return sz;
    }

    //非阻塞接收
    ssize_t NonBlockRecv(void *buf, size_t len) {
        return Recv(buf, len, MSG_DONTWAIT); // MSG_DONTWAIT 表示当前接收为非阻塞。
    }

    ssize_t Send(const void *buf, size_t len, int flag = 0) {
            // ssize_t send(int sockfd, void *data, size_t len, int flag);
            ssize_t ret = send(_sockfd, buf, len, flag);
            // 当成功发送数据时，它返回发送的字节数，这个值总是大于或等于 0。
            // 当发送失败时，它返回 -1，并且全局变量 errno 会被设置为指示错误的代码。
            if (ret <0) {
                if (errno == EAGAIN || errno == EINTR) {
                    return 0;
                }
                DEBUG_LOG("SOCKET SEND FAILED!!");
                return -1;
            }
            return ret;//实际发送的数据长度
    }
    //非阻塞发送
    ssize_t NonBlockSend(void *buf, size_t len) {
        if (len == 0) return 0;
        return Send(buf, len, MSG_DONTWAIT); // MSG_DONTWAIT 表示当前发送为非阻塞。
    }


    // 关闭套接字
    void Close()
    {
        if (_sockfd != -1)
        {
            close(_sockfd);
            //重新设置为-1
            _sockfd=-1;
        }
    }

     // 设置套接字选项---开启地址端口重用
    void ReuseAddress()
    {
        //设置允许地址重用
        int val = 1;
        setsockopt(_sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&val, sizeof(int));
        //设置允许端口号重用
        val = 1;
        setsockopt(_sockfd, SOL_SOCKET, SO_REUSEPORT, (void *)&val, sizeof(int));
    }

    // 设置套接字非阻塞属性
    void Fcntl()
    {
        //获取标志位
        int flag = fcntl(_sockfd, F_GETFL);
        //设置标志位
        fcntl(_sockfd, F_SETFL, flag | O_NONBLOCK);
    }

    // 创建一个服务端连接
    bool CreateServer(uint32_t port)
    {
        //1. 创建套接字，2. 绑定地址，3. 开始监听，4. 设置非阻塞， 5. 启动地址重用
        if (_sockfd != -1)
            return false;
        if(!CreateSocket()) return false;
        if(!Bind(port)) return false;
        if(!Listen(10)) return false;
        Fcntl();
        ReuseAddress();
        return true;
    }

    // 创建一个客户端连接
    bool CreateClient(uint32_t port, std::string ip)
    {
        //1. 创建套接字，2.指向连接服务器
       if(!CreateSocket()) return false;
       if(!Connect(port, ip)) return false;
       return true;
    }
};

class Poller;
class EventLoop;
// 事件管理模块
class Channel
{
private:
    int _fd;
    EventLoop *_loop;
    // Poller *_poller;
    uint32_t _events;  // 当前需要监控的事件
    uint32_t _revents; // 当前连接触发的事件
    using EventCallback = std::function<void()>;
    EventCallback _read_callback;  // 可读事件被触发的回调函数
    EventCallback _write_callback; // 可写事件被触发的回调函数
    EventCallback _error_callback; // 错误事件被触发的回调函数
    EventCallback _close_callback; // 连接断开事件被触发的回调函数
    EventCallback _event_callback; // 任意事件被触发的回调函数
public:
    Channel(EventLoop *loop,int fd) : _fd(fd), _loop(loop), _events(0), _revents(0) {}
    //, _read_callback(nullptr), _write_callback(nullptr), _error_callback(nullptr), _close_callback(nullptr), _event_callback(nullptr) {}
    //设置事件发生时的回调函数
    void SetReadCallback(const EventCallback &cb){ _read_callback = cb; }
    void SetWriteCallback(const EventCallback &cb){ _write_callback = cb; }
    void SetErrorCallback(const EventCallback &cb){ _error_callback = cb; }
    void SetCloseCallback(const EventCallback &cb){ _close_callback = cb; }
    void SetEventCallback(const EventCallback &cb){ _event_callback = cb; }
    //设置触发事件
    void SetRevents(int revents){ _revents = revents; }

    int Fd(){ return _fd; }

    uint32_t Events(){ return _events; }

    uint32_t Revents(){ return _revents; }

    // 当前是否可读
    bool ReadAble(){ return _events & EPOLLIN; }

    // 当前是否可写
    bool WriteAble(){ return _events & EPOLLOUT; }

    // 启动读事件监控
    void EnableRead()
    {
        _events |= EPOLLIN;
        Update();
    }

    // 启动写事件监控
    void EnableWrite()
    {
        _events |= EPOLLOUT;
        Update();
    }

    // 关闭读事件监控
    void DisableRead()
    {
        if (ReadAble())
        {
            _events ^= EPOLLIN;
            Update();
        }
    }

    // 关闭写事件监控
    void DisableWrite()
    {
        if (WriteAble())
        {
            _events ^= EPOLLOUT;
            Update();
        }
    }

    // 关闭所有事件监控
    void DisableAl1()
    {
        _events = 0;
        Update();
    }

    // 发生错误时关闭所有触发事件监控
    void DisTriggerAl1(){ _revents = 0; }

    // 因为使用了_poller中的成员函数，使用不能在这里直接定义，类外定义
    // 移除监控
    void Remove();

    // 更新监控
    void Update();

    // 事件处理，一旦连接触发了事件，就调用这个函数，自己触发了什么事件如何处理自己
    void HandleEvent()
    {
        if (EPOLLIN & _revents)
        {
            if (_event_callback)
                _event_callback();
            if (_read_callback)
                _read_callback();
        }

        if (EPOLLOUT & _revents)
        {
            if (_event_callback)
                _event_callback();
            if (_write_callback)
                _write_callback();
        }
        if (EPOLLERR & _revents)
        {
            if (_event_callback)
                _event_callback();
            if (_error_callback)
                _error_callback();
        }
        if (EPOLLHUP & _revents)
        {
            if (_event_callback)
                _event_callback();
            if (_close_callback)
                _close_callback();
        }

        // EPOLLIN：有数据可读。
        // EPOLLRDHUP：对端已经关闭连接或者半关闭写方向。
        // EPOLLPRI：有带外（out-of-band）数据可读，通常用于指示有紧急数据。
        // if ((_revents & EPOLLIN) || (_revents & EPOLLRDHUP) || (_revents & EPOLLPRI)) {
        //         /*不管任何事件，都调用的回调函数*/
        //         if (_read_callback) _read_callback();
        //     }
        //     /*有可能会释放连接的操作事件，一次只处理一个*/
        //     if (_revents & EPOLLOUT) {
        //         if (_write_callback) _write_callback();
        //     }else if (_revents & EPOLLERR) {
        //         if (_error_callback) _error_callback();//一旦出错，就会释放连接，因此要放到前边调用任意回调
        //     }else if (_revents & EPOLLHUP) {
        //         if (_close_callback) _close_callback();
        //     }
        //     if (_event_callback) _event_callback();
    }
};



// //监控事件模块
// #define MAX_EPOLLEVENTS 1024
// class Poller
// {
// private:
//     int _epfd;
//     struct epoll_event _evs[MAX_EPOLLEVENTS];
//     std::unordered_map<int, Channel*> _channels;

// private:
//     // 对epo11的直接操作
//     void Update(Channel *channel, int op)
//     {
//         int fd = channel->Fd();
//         epoll_event ev;
//         // 要将fd也一同绑定到ev当中，不然数据触发时无法通过fd找到对应的channel
//         ev->data.fd = fd;
//         ev->events = channel->Events();
//         epoll_ctl(_epfd, op, fd, &ev);
//     }

//     // 判断一个Channe1是否已经添加了事件监控
//     bool HasChannel(Channel *channel)
//     {

//         // 不能使用[]查找，因为没有找到时会进行插入，键为fd,值为nullptr
//         //   int fd=channel->Fd();
//         //   return _channels[re]==nullptr?false:true;
//         int fd = channel->Fd();
//         auto it = _channels.find(fd);
//         return it != _channels.end() ? true : false;
//     }

// public:
//     Poller():_epfd(epoll_create(MAX_EPOLLEVENTS))
//     {
//         //_epfd = epoll_create(MAX_EPOLLEVENTS);
//         if (_epfd < 0)
//         {
//             ERR_LOG("epoll_create:%s", strerror(_epfd));
//         }
//     }

//     // 添加或修改监控事件
//     void UpdateEvent(Channel *channel)
//     {
//         if (HasChannel(channel))
//         {
//             // DEBUG_LOG("修改监听fd");
//             Update(channel, EPOLL_CTL_MOD);
//         }
//         else
//         {
//             int re = channel->Fd();
//             //DEBUG_LOG("新加入的监听fd:%d", re);
//             //_channels[re]=channel;
//             _channels.insert({re, channel});
//             Update(channel, EPOLL_CTL_ADD);
//         }
//     }

//     // // 有bug的移除监控
//     // void RemoveEvent(Channel *channel)
//     // {
//     //     Update(channel, EPOLL_CTL_DEL);
//     // }

//     //移除监控
//     void RemoveEvent(Channel *channel)
//     {
//         if(HasChannel(channel))
//         {
//             //不使用erase，释放之后，下次新的连接会沿用这个fd，使用的也是之前绑定在哈希中的channel
//             _channels.erase(channel->Fd());
//             Update(channel, EPOLL_CTL_DEL);
//         }

//     }

//     // 开始监控，返回活跃连接
//     void Poll(std::vector<Channel *> *active)
//     {
//         //在多线程中_epfd都是不一样的,每一个线程都拥有自己的epoll句柄
//         int nfds = epoll_wait(_epfd, _evs, MAX_EPOLLEVENTS, -1);
//         if (nfds < 0)
//         {
//             //在这里一个使用错误码判断，而不是返回值判断
//             // if (nfds == EINTR)
//             // {
//             //     return;
//             // }
//             if (errno == EINTR)
//             {
//                 return;
//             }
//             ERR_LOG("epoll_wait err:%s", strerror(nfds));
//             // std::cout<<strerror(nfds)<<std::endl;
//             abort();
//         }
//         for (int i = 0; i < nfds; i++)
//         {
//             int fd = _evs[i].data.fd;
//             Channel *channel = _channels[fd];
//             // DEBUG_LOG("处理fd:%d", fd);
//             assert(channel != nullptr);
//             channel->SetRevents(_evs[i].events);
//             active->push_back(channel);
//             // channel->HandleEvent();
//         }

//         return;
//     }
// };

#define MAX_EPOLLEVENTS 1024
class Poller {
    private:
        int _epfd;
        struct epoll_event _evs[MAX_EPOLLEVENTS];
        std::unordered_map<int, Channel *> _channels;
    private:
        //对epoll的直接操作，op进行的具体操作添加，修改，删除
        void Update(Channel *channel, int op) {
            // int epoll_ctl(int epfd, int op,  int fd,  struct epoll_event *ev);
            int fd = channel->Fd();
            struct epoll_event ev;
            // 要将fd也一同绑定到ev当中，不然数据触发时无法通过fd找到对应的channel
            ev.data.fd = fd;
            ev.events = channel->Events();
            int ret = epoll_ctl(_epfd, op, fd, &ev);
            if (ret < 0) {
                ERR_LOG("EPOLLCTL FAILED!");
            }
        }
        //判断一个Channel是否已经添加了事件监控
        bool HasChannel(Channel *channel) {
            // 不能使用[]查找，因为没有找到时会进行插入，键为fd,值为nullptr
            auto it = _channels.find(channel->Fd());
            if (it == _channels.end()) {
                return false;
            }
            return true;
        }
    public:
        Poller() {
            //创建epoll句柄
            _epfd = epoll_create(MAX_EPOLLEVENTS);
            if (_epfd < 0) {
                ERR_LOG("EPOLL CREATE FAILED!!");
                abort();//退出程序
            }
        }
        //添加或修改监控事件
        void UpdateEvent(Channel *channel) {
            bool ret = HasChannel(channel);
            if (ret == false) {
                //不存在则添加
                _channels.insert(std::make_pair(channel->Fd(), channel));
                return Update(channel, EPOLL_CTL_ADD);
            }
            return Update(channel, EPOLL_CTL_MOD);
        }
        //移除监控
        void RemoveEvent(Channel *channel) {
            auto it = _channels.find(channel->Fd());
            if (it != _channels.end()) {
                //不使用erase，释放之后，下次新的连接会沿用这个fd，使用的也是之前绑定在哈希中的channel
                _channels.erase(it);
            }
            Update(channel, EPOLL_CTL_DEL);
        }
        //开始监控，返回活跃连接
        void Poll(std::vector<Channel*> *active) {
            // int epoll_wait(int epfd, struct epoll_event *evs, int maxevents, int timeout)
            int nfds = epoll_wait(_epfd, _evs, MAX_EPOLLEVENTS, -1);
            if (nfds < 0) {
                //在这里一个使用错误码判断，而不是返回值nfds判断
                if (errno == EINTR) {
                    return ;
                }
                ERR_LOG("EPOLL WAIT ERROR:%s\n", strerror(errno));
                abort();//退出程序
            }
            for (int i = 0; i < nfds; i++) {
                auto it = _channels.find(_evs[i].data.fd);
                assert(it != _channels.end());
                it->second->SetRevents(_evs[i].events);//设置实际就绪的事件
                active->push_back(it->second);
            }
        }
};






//非活跃销毁任务管理
// class timer
// {
// public:
//     timer(uint64_t taskid, int timeout, std::function<void()> task)
//         : taskid_(taskid), timeout_(timeout), task_(task)
//     {
//     }

//     // 时间到，对象被销毁时，执行任务
//     ~timer()
//     {
//         task_();
//     }

//     uint32_t DelayTime() { return timeout_; }

// private:
//     uint64_t taskid_;            // 任务编号,不是线程id
//     int timeout_;                // 间隔时间
//     std::function<void()> task_; // 执行任务
// };


using TaskFunc = std::function<void()>;
using ReleaseFunc = std::function<void()>;
//非活跃销毁任务管理
class TimerTask{
private:
    uint64_t taskid_;            // 任务编号,不是线程id
    int timeout_;                // 间隔时间
    TaskFunc task_;             // 需要执行的任务
    bool _canceled;     // false-表示没有被取消， true-表示被取消,通过设置标注位任务取消了，避免任务的执行
    ReleaseFunc _release; //用于删除TimerWheel中保存的定时器对象信息
public:
    TimerTask(uint64_t taskid, int timeout, TaskFunc task)
        : taskid_(taskid), timeout_(timeout), task_(task), _canceled(false)
    {}

    void SetRelease(const ReleaseFunc &cb) { _release = cb; }
    void Cancel() { _canceled = true; }
    // 时间到，对象被销毁时，执行任务
    ~TimerTask()
    {
        //如果不设置标注位限制，时间到达后，引用计数为0，依然会执行任务
        //如果任务对象提前被取消，则不执行任务
        if (_canceled == false)    
            task_(); 
        //顺带删除TimerWheel中保存的定时器对象信息，不然client4测试时会出现TimerTask对象已经销毁，但后续任然执行任意事件回调函数时刷新活跃值，导致程序崩溃
        _release(); 
    }

    //返回刷新时间
    uint32_t DelayTime() { return timeout_; }
};



//时间轮
class EventLoop;
class TimerWheel
{
private:
    int tick_;                                               //当前的秒针，走到哪里释放哪里，释放哪里，就相当于执行哪里的任务
    int capacity_;                                           //表盘最大数量---也就是最大延迟时间
    std::vector<std::vector<std::shared_ptr<TimerTask>>> _wheel; // 时间轮
    std::unordered_map<int, std::weak_ptr<TimerTask>> _timers;   // 通过fd找到weak_ptr,方便判断和构造对象，并且·使用weak_ptr因为引用计数不会增加
    // 可能会有多个线程同时操作_timers,对定时器进行添加或删除，产生线程安全问题，因此把所有对于定时器的操作放到同一个线程里面执行，这样不会有效率问题吗？

    // 以秒为单位滚动事件轮
    int _timerfd;//定时器描述符--可读事件回调就是读取计数器，执行定时任务
    EventLoop *_loop;
    std::unique_ptr<Channel> _timer_channel;

private:
    void RemoveTimer(uint64_t id) {
        auto it = _timers.find(id);
        if (it != _timers.end()) {
            _timers.erase(it);
        }
    }
    // 创建事件通知fd，目的是为了让时间轮每秒中向后转动一次
    static int CreatTimerfd()
    {
        int timerfd = timerfd_create(CLOCK_MONOTONIC, 0);
        if (timerfd < 0) {
            ERR_LOG("TIMERFD CREATE FAILED!");
            abort();
        }
        //设置通知时间
        struct itimerspec itime;
        itime.it_value.tv_sec = 1;
        itime.it_value.tv_nsec = 0;//第一次超时时间为1s后
        itime.it_interval.tv_sec = 1; 
        itime.it_interval.tv_nsec = 0; //第一次超时后，每次超时的间隔时
        timerfd_settime(timerfd, 0, &itime, NULL);
        return timerfd;
    }

    //读取超时次数
    int ReadTimerfd()
    {
        //有可能因为其他描述符的事件处理花费事件比较长，然后在处理定时器描述符事件的时候，有可能就已经超时了很多次
        //read读取到的数据times就是从上一次read之后超时的次数
        u_int64_t times;
        int n = read(_timerfd, &times, 8);
        if (n < 0)
        {
            ERR_LOG("TIMERFD READ FAIL:%s", strerror(n));
            abort();
        }
        
        return times;
    }

    // 时间轮滚动
    //这个函数应该每秒钟被执行一次，相当于秒针向后走了一步
    void RunTimerTask()
    {
        tick_++;
        if (_wheel[(tick_ + capacity_) % 60].size() > 0)
        {
            // 删除指针，引用计数为0的，自动调用析构函数执行任务
            _wheel[(tick_ + capacity_) % 60].clear();
        }
    }

    // 读取_timerfd数据+滚动时间轮
    void RunTimer()
    {
        //根据实际超时的次数，执行对应的超时任务
        int times=ReadTimerfd();
        for(int i=0;i<times;i++){
            RunTimerTask();
        } 
    }

    bool TimerIsInLoop();
    void TimerQueueInLoop(std::function<void()> fc);

    // 添加定时器,这个函数是有线程安全问题的，定时器跟EventLoop是一对一的，那么就不允许被非对应的EvnntLoop线程执行
    // 为什么其它线程会进入到这个定时器里面执行这个函数，多线程执行流，67节21分
    void TimerAddInLoop(uint64_t taskid, int timeout, std::function<void()> task)
    {
        std::shared_ptr<TimerTask> st(new TimerTask(taskid, timeout, task));
        st->SetRelease(std::bind(&TimerWheel::RemoveTimer, this, taskid));
        // 加入时间轮中
        _wheel[(tick_ + timeout) % 60].push_back(st);
        // 加入哈希表中方便查找，使用weak_ptr因为引用计数不会增加
        _timers[taskid] = std::weak_ptr<TimerTask>(st);
    }

    // 刷新定时器
    //本质上通过taskid找到对应的weak_ptr构造出一个shared_ptr添加到时间轮当中
    void TimerRefreshInLoop(uint64_t taskid)
    {
        // 判断
        if (!HasTimer(taskid)){
            return;
        }
        // 通过fd找到weak_ptr,方便判断和构造对象
        std::shared_ptr<TimerTask> sdelay = _timers[taskid].lock();
        // 再次加入到时间轮当中
        _wheel[(tick_ + (sdelay->DelayTime())) % 60].push_back(sdelay);
    }

    // 取消定时任务
    void TimerCancelInLoop(uint64_t taskid)
    {
        //除了要删除taskid外，还要避免任务被执行   
        //删除TimerWheel中保存的定时器对象信息
        auto it = _timers.find(taskid);
        if (it != _timers.end()) {
            _timers.erase(it);
        }
        // 通过fd找到weak_ptr,构造shared_ptr，修改标志位，防止后续时间到时，任务依然被执行
        auto pt = it->second.lock();
        if (pt) pt->Cancel();
    }

public:
    TimerWheel(EventLoop *loop = nullptr)
        : tick_(0), capacity_(60), _wheel(capacity_), _timerfd(CreatTimerfd()), _loop(loop), _timer_channel(new Channel(loop,_timerfd))
    {
        _wheel.resize(60);
        // 默认带一个this指针
        _timer_channel->SetReadCallback(std::bind(&TimerWheel::RunTimer, this)); // 设置读回调函数
        _timer_channel->EnableRead();                                            // 添加监控
    }

    //添加任务
    // std::bind 需要指定对象的实例来调用非静态成员函数，因为它需要一个上下文（即对象实例）来执行该成员函数。
    // 在TimerAdd 方法中，TimerAddInLoop 是一个非静态成员函数，因此需要与 TimerWheel 类的一个实例关联起来才能被调用。
    // 然而， std::bind 调用中没有提供这个实例。这会导致编译错误，因为编译器不知道在哪个 TimerWheel 实例上调用 TimerAddInLoop。
    void TimerAdd(uint64_t taskid, int timeout, std::function<void()> task)
    {
        if (TimerIsInLoop()){
            TimerAddInLoop(taskid, timeout, task);
        }
        else
            TimerQueueInLoop(std::bind(&TimerWheel::TimerAddInLoop, this, taskid, timeout, task));
        // else TimerQueueInLoop(std::bind(TimerWheel::TimerAddInLoop,taskid,timeout,task));错误
    }

    void TimerRefresh(uint64_t taskid)
    {
        if (TimerIsInLoop()){
            TimerRefreshInLoop(taskid);
        }
        else
            TimerQueueInLoop(std::bind(&TimerWheel::TimerRefreshInLoop, this, taskid));
    }

    void TimerCancel(uint64_t taskid)
    {
        if (TimerIsInLoop()){
            TimerCancelInLoop(taskid);
        }
        else
            TimerQueueInLoop(std::bind(&TimerWheel::TimerCancelInLoop, this, taskid));
    }

     // 判断是否已经加入时间轮中
    bool HasTimer(uint64_t taskid)
    {
        auto num = _timers.begin();
        while (num != _timers.end())
        {
            if (num->first == taskid)
            {
                return true;
            }
            num++;
        }
        return false;
    }
};

//整合模块
class EventLoop
{
private:
    using Functor = std::function<void()>;
    std::thread::id _thread_id;              // 线程ID
    int _event_fd;                           // eventfd唤醒I0事件监控有可能导致的阻塞
    std::unique_ptr<Channel> _event_channel; // 管理_event_fd,用智能指针管理，loop释放时也能一起释放
    Poller _poller;                          // 进行所有描述符的事件监控
    std::vector<Functor> _tasks;             // 任务池
    std::mutex _mutex;                       // 实现任务池操作的线程安全
    TimerWheel *_wheel;                      // 事件轮
private:
    // 为什么在这里就能保证任务被自己对应的EventLoop线程执行
    // 执行任务池中的所有任务
    void RunAllTask(){
        //交换任务池中的任务
        std::vector<Functor> tasks;
        // 增加一个作用域，出了这个作用域锁自动释放
        // 创建一个互斥量的锁，并在构造时立即锁定它，然后在对象销毁时自动解锁。
        {
            std::unique_lock<std::mutex> unlock(_mutex);
            _tasks.swap(tasks);
        }
        // 为什么在这就是它自己的线程执行？
        for (auto &f : tasks)
        {
            f();
        }
    }

    // 如果CreateEventFd()函数不需要访问类的任何非静态成员变量，
    // 并且它的功能是与类无关的（例如，它只是一个辅助函数，用于创建一个事件文件描述符），
    // 那么你可以将其设置为static。这样，它就可以在没有类实例的情况下被调用。
    static int CreateEventFd(){
        int event_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
        return event_fd;
    }

    void ReadEventfd() {
        uint64_t res = 0;
        int ret = read(_event_fd, &res, sizeof(res));
        if (ret < 0) {
            //EINTR -- 被信号打断；   EAGAIN -- 表示无数据可读
            if (errno == EINTR || errno == EAGAIN) {
                return;
            }
            ERR_LOG("READ EVENTFD FAILED!");
            abort();
        }
        return ;
    }
    void WeakUpEventFd() {
        uint64_t val = 1;
        int ret = write(_event_fd, &val, sizeof(val));
        if (ret < 0) {
            if (errno == EINTR) {
                return;
            }
            ERR_LOG("WRITE EVENTFD FAILED!");
            abort();
        }
        return ;
    }
public:
    EventLoop()
        : _thread_id(std::this_thread::get_id()), _event_fd(CreateEventFd()), _event_channel(new Channel(this,_event_fd)), _wheel(new TimerWheel(this))
    {
        // 传this指针是因为函数内部会访问类的成员，方便在外部被调用时，也就能够使用,设置为static是因为它没有this指针
        _event_channel->SetReadCallback(std::bind(&EventLoop::ReadEventfd, this));
        _event_channel->EnableRead();
    }

    // 三步走--事件监控-》就绪事件处理-》执行任务,当没有事件来时，会阻塞在事件监控中，导致任务一直不被执行，因此我们需要自主设置触发事件的到来
    void Start(){
        while(1)
        {
            // 事件监控
            std::vector<Channel *> actives;
            _poller.Poll(&actives);
            // 就绪事件处理
            //有些需要保障线程安全的操作可能会压入任务队列中
            for (auto c : actives)
            {
                c->HandleEvent();
            }
            RunAllTask();
        }
    }

    // 判断当前线程是否为EventLoop对应的线程，this_thread
    bool IsInLoop(){
        return _thread_id == std::this_thread::get_id();
    }

    // 判断将要执行的任务是否处于当前线程中，如果是则执行，不是则压入队列。
    void RunInLoop(const Functor &cb){
        if (IsInLoop())
        {
            cb();
        }
        else
        {
            QueueInLoop(cb);
        }
    }

    // 将操作压入任务池
    void QueueInLoop(const Functor &cb){
        // 确保线程安全
        {
            std::unique_lock<std::mutex> unlock(_mutex);
            _tasks.push_back(cb);
        }
        // 防止_poller阻塞，写入数据，触发读事件
        WeakUpEventFd();
    }

    // 添加/修改描述符的事件监控
    void UpdateEvent(Channel *channel){
        _poller.UpdateEvent(channel);
    }

    // 移除描述符的监控
    void RemoveEvent(Channel *channel){
        _poller.RemoveEvent(channel);
    }
    //添加定时任务
    void TimerAdd(uint64_t taskid, int timeout, std::function<void()> task){
        _wheel->TimerAdd(taskid, timeout, task);
    }
    //刷新定时任务
    void TimerRefresh(uint64_t taskid){
        _wheel->TimerRefresh(taskid);
    }
    //取消定时任务
    void TimerCancel(uint64_t taskid){
        _wheel->TimerCancel(taskid);
    }

    bool HasTimer(uint64_t taskid){
        return _wheel->HasTimer(taskid);
    }
};

//管理Loop的线程
class LoopThread{
private:
    /*用于实现_loop获取的同步关系，避免线程创建了，但是_loop还没有实例化之前去获取_loop*/
    std::mutex _mutex;//互斥锁
    std::condition_variable _cond;//条件变量，保障获取EventLoop时，一定不为nullptr
    EventLoop* _loop;//线程对应的EventLoop,保障是对应的线程创建，所以使用指针，先创建线程再创建EventLoop
    std::thread _thread;//创建的线程
private:
    // /*实例化 EventLoop 对象，唤醒_cond上有可能阻塞的线程，并且开始运行EventLoop模块的功能*/
    //创建线程对应的EventLoop
    void CreateEventLoop(){
        //使用局部变量，限制其生命周期随着线程销毁而销毁
        EventLoop loop;
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _loop=&loop;
            //唤醒条件变量中所有等待的线程
            _cond.notify_all();
        }
        DEBUG_LOG("CREATE THREAD SUCCESS");
        //启动线程，里面有while（1）循环
        _loop->Start();
    }
public:
    /*创建线程，设定线程入口函数*/
    LoopThread():
    _loop(nullptr)
    ,_thread(std::thread(&LoopThread::CreateEventLoop,this))
    {}

    //有一个问题：我们如何确保获取loop时它不为nullptr，因为可能会有我们还没创建loop时，就有访问loop的情况出现
    //锁+条件变量
    //获取loop
    EventLoop* GetLoop(){
        EventLoop*loop;
        {
            std::unique_lock<std::mutex> lock(_mutex);
        // []：不捕获任何变量。
        // [=]：以值捕获所有外部变量。
        // [&]：以引用捕获所有外部变量。
        // [x]：仅以值捕获变量 x。
        // [&x]：仅以引用捕获变量 x。
        // [=, &x]：以值捕获所有外部变量，但以引用捕获 x。
        // [&, x]：以引用捕获所有外部变量，但以值捕获 x（注意这种用法较少见，因为它通常不是必要的）。
        //wait的第二变量为函数返回的bool值，只要为false则一直阻塞
            _cond.wait(lock,[&](){return _loop!=nullptr;});
            loop=_loop;
        }
        //DEBUG_LOG("GET LOOP");
        return loop;
    }
};


//为什么要用Loopthread*,而不能用LoopThread
//LoopThread 类中包含了不可移动（或不可复制）的成员变量 std::mutex 和 std::condition_variable。
//由于 LoopThread 类包含了不可移动的成员，编译器会隐式删除移动构造函数。这意味着你不能通过移动操作来传递或赋值 LoopThread 对象。
//std::vector<LoopThread>，那么每次向vector中添加元素时，都会复制或移动LoopThread对象
//管理loopd线程池模块
//需要考虑0个或多个从属线程的情况
class LoopThreadPool{
    EventLoop* _baseloop;//主EventLoop,当从属线程为0时，都由主Eventloop监控和处理所有事件
    int _thread_count;//从属线程的数量
    std::vector<LoopThread*> _threads;//从属线程池
    int _next_loop_idx;//选择一个eventloop
    std::vector<EventLoop*> _loops;//分配多个从属线程的loop
public:
    LoopThreadPool(EventLoop*baseloop):_baseloop(baseloop),_thread_count(0),_next_loop_idx(0){}

    //设置线程数量
    void SetThreadCount(int thread_count){
         _thread_count=thread_count;
    }

    //创建EventThread
    void Create(){
        if(_thread_count>0){
            _threads.resize(_thread_count);
            for(int i=0;i<_thread_count;i++){
                _threads[i]=new LoopThread();
                _loops.push_back(_threads[i]->GetLoop());
            }
        }
    }
    //线程分配
    EventLoop* GetLoop(){
        if(_thread_count==0){
            return _baseloop;
        }
        _next_loop_idx=(_next_loop_idx+1)%_thread_count;
        return _loops[_next_loop_idx];
    }
};

//连接状态
typedef enum
{
    DISCONNECTED,  //--连接关闭状态
    CONNECTING,   //.-连接建立成功-待处理状态
    CONNECTED,    //--连接建立完成，各种设置已完成，可以通信的状态;
    DISCONNECTING //--待关闭状态
} ConnStatu;
//协议上下文
class Any
{
private:
    class holder
    {
    public:
        holder() {}
        virtual ~holder() {}
        virtual const std::type_info &Type() = 0;
        virtual holder *Clone() = 0;
    };

    template <class T>
    class placeholder : public holder
    {
    public:
        placeholder(T val) : val_(val){}
        // 获取值
        T *getVal(){
            return &val_;
        }

        // 获取数据类型
        const std::type_info &Type(){
            return typeid(val_);
        }

        // 克隆
        placeholder *Clone(){
            return new placeholder<T>(val_);
        }

    private:
        T val_;
    };
private:
    holder *_content;
public:
    template <class T>
    Any(T val) : _content(new placeholder<T>(val)){
    }
    Any(const Any& a){
        this->_content=a._content->Clone();
    }
    Any() : _content(nullptr){
    }
    ~Any() {delete _content;}

    Any& swap(Any& other){
        std::swap(_content,other._content);
        return *this;
    }

    template <class T>
    T *getVal()
    {
        //想要获取的数据类型，必须和保存的数据类型一致
        assert(typeid(T) == (_content->Type()));
        return ((placeholder<T> *)_content)->getVal();
    }

    template <class T>
    Any& operator=(const T& val)
    {
        // if (_content != nullptr)
        //     delete _content;
        //_content = new placeholder<T>(val);
        //为val构造一个临时的通用容器，然后与当前容器自身进行指针交换，临时对象释放的时候，原先保存的数据也就被释放
        Any(val).swap(*this);
        return *this;
    }

    Any& operator=(const Any& a)
    {
        //_content = _content->Clone();
        Any(a).swap(*this);
        return *this;
    }
};

//可能会有多个线程对同一个Connection进行操作,为防止被提前关闭，使用智能指针管理，在服务器里进行最终的释放
class Connection;
using PtrConnection = std::shared_ptr<Connection>;

class Connection:public std::enable_shared_from_this<Connection>//内部生成有weak_ptr，可以根据这个生成shared_ptr
{
private:
    uint64_t _conn_id; // 连接唯一ID
    // uint64_t _timer_id; //定时器ID，必须是唯一的，这块为了简化操作使用conn_id作为定时器ID
    int _sockfd;                       // 套接字ID
    Socket _socket;                    // 管理套接字
    bool _enable_inactive_release;     // 连接是否启动非活跃销毁的判断标志，默认为false
    EventLoop *_loop;                  // 连接所关联的一个EventLoop
    ConnStatu _statu;                  // 连接状态
    std::shared_ptr<Channel> _channel; // 监控套接字
    Buffer _in_buffer;                 // 输入缓冲区——存放从socket中读取到的数据
    Buffer _out_buffer;                // 输出缓冲区——写事件触发后向对端发送的数据
    Any _context;                      // 请求的接收处理连接上下文
    /*这四个回调函数，是让服务器模块来设置的（其实服务器模块的处理回调也是组件使用者设置的）*/
    /*换句话说，这几个回调都是组件使用者使用的*/
    using ConnectedCallback = std::function<void(const PtrConnection &)>;         // 连接事件到来后的回调函数
    using MessageCallback = std::function<void(const PtrConnection &, Buffer *)>; // 数据到来后的回调函数
    using ClosedCallback = std::function<void(const PtrConnection &)>;            // 关闭事件到来后的回调函数
    using AnyEventCallback = std::function<void(const PtrConnection &)>;          // 任意事件到来后的回调函数
    ConnectedCallback _connected_callback;
    MessageCallback _message_callback;
    ClosedCallback _closed_callback;
    AnyEventCallback _event_callback;
    /*组件内的连接关闭回调--组件内设置的，因为服务器组件内会把所有的连接管理起来，一旦某个连接要关闭*/
    /*就应该从管理的地方移除掉自己的信息*/
    ClosedCallback _server_close_callback;
private:
    /*设置五个channel的事件回调函数*/
    //描述符可读事件触发后调用的函数，接收socket数据放到接收缓冲区中，然后调用_message_callback
    void HandleRead(){
        ///1. 接收socket的数据，并放到读缓冲区
        char buffer[65536];
        int re=_socket.NonBlockRecv(buffer,65535);
        if(re<0){
            //注意在这里不能直接释放连接，因为读写缓冲区中可能还有数据
           return ShutdownInLoop();
        }
        //这里的等于0表示的是没有读取到数据，而并不是连接断开了，连接断开返回的是-1
        //将数据放入输入缓冲区,写入之后顺便将写偏移向后移动
        _in_buffer.WriteAndPush(buffer,re);
        //2. 调用message_callback进行业务处理
        if(_in_buffer.ReadAbleSize()>0){
            //shared_from_this--从当前对象自身获取自身的shared_ptr管理对象
            _message_callback(shared_from_this(),&_in_buffer);
        }
    }

    //描述符可写事件触发后调用的函数，将发送缓冲区中的数据通过socket发送
    void HandleWrite(){
        ssize_t ret = _socket.NonBlockSend(_out_buffer.ReadPosition(), _out_buffer.ReadAbleSize());
        if (ret < 0) {
            //发送错误就该关闭连接了，但是要先将接收缓冲区的数据处理干净
            if (_in_buffer.ReadAbleSize() > 0) {
                _message_callback(shared_from_this(), &_in_buffer);
            }
            return Release();//这时候就是实际的关闭释放操作了。
        }
        _out_buffer.MoveReadOffset(ret);//千万不要忘了，将读偏移向后移动
        if (_out_buffer.ReadAbleSize() == 0) {
            _channel->DisableWrite();// 没有数据待发送了，关闭写事件监控
            //如果当前是连接待关闭状态，则有数据，发送完数据释放连接，没有数据则直接释放
            if (_statu == DISCONNECTING) {
                return Release();
            }
        }
        return;
    }
    //描述符触发挂断事件
    void HandleClose() {
        /*一旦连接挂断了，套接字就什么都干不了了，因此有数据待处理就处理一下，完毕关闭连接*/
        if (_in_buffer.ReadAbleSize() > 0) {
            _message_callback(shared_from_this(), &_in_buffer);
        }
        return Release();
    }
    //描述符触发出错事件
    void HandleError() {
        return HandleClose();
    }
    //描述符触发任意事件: 1. 刷新连接的活跃度--延迟定时销毁任务；  2. 调用组件使用者的任意事件回调
    void HandleEvent(){
        if(_enable_inactive_release=true) _loop->TimerRefresh(_conn_id);
        if(_event_callback) _event_callback(shared_from_this());//shared_from_this（）在这里用完即销毁
    }

    // 连接建立就绪后，进行的一系列操作
    void EstablishedInLoop(){
        //1.启动读事件监控 2.设置连接状态 3.调用组件使用者的连接到来后的事件回调
        assert(_statu == CONNECTING);//当前的状态必须一定是上层的半连接状态
        _channel->EnableRead();
        _statu=CONNECTED;
        if(_connected_callback) _connected_callback(shared_from_this());
    }

    //这个接口才是实际的释放接口
    //服务器释放对connection的管理
    void ReleaseInLoop(){
        //DEBUG_LOG("ReleaseInLoop:%s",this);
        //1. 修改连接状态，将其置为DISCONNECTED
        _statu=DISCONNECTED;
        //2. 移除连接的事件监控
        _channel->Remove();
        _channel->DisTriggerAl1();
        //3. 关闭描述符
        _socket.Close();
        //注意调用顺序
        //4. 如果当前定时器队列中还有定时销毁任务，则取消任务
        if (_loop->HasTimer(_conn_id)) CancelInactiveReleaseInLoop();
        //if(_loop->HasTimer(_conn_id)) _loop->TimerCancel(_conn_id);//任务取消
        //5. 调用关闭回调函数，避免先移除服务器管理的连接信息导致Connection被释放，再去处理会出错，因此先调用用户的回调函数
        if(_closed_callback) _closed_callback(shared_from_this());
        //移除服务器内部管理的连接信息
        if(_server_close_callback) _server_close_callback(shared_from_this());
    }

    // 发送数据，只是将数据放到发送缓冲区，启动写事件监控              
    void SendInLoop(Buffer& buf){
        if (_statu == DISCONNECTED) return ;
        _out_buffer.WriteBufferAndPush(buf);
        if(_channel->WriteAble()==false)
            _channel->EnableWrite();
    }

    // 提供给组件使用者的关闭接口--并不实际关闭，需要判断有没有数据待处理,或者发送
    void ShutdownInLoop(){
        //设置标志，后续判断缓冲区里没有数据时直接关闭
        _statu=DISCONNECTING;
        if(_in_buffer.ReadAbleSize()>0){
            if(_message_callback) _message_callback(shared_from_this(),&_in_buffer);
        }
        if(_out_buffer.ReadAbleSize()>0){
            if(_channel->WriteAble()==false){
                _channel->EnableWrite();
            }
        }
        if(_out_buffer.ReadAbleSize()==0){
            Release();
        }
    }                   
    // 启动非活跃销毁，并定义多长时间无通信就是非活跃，添加或者刷新定时任务
    void EnableInactiveReleaseInLoop(int sec){
        //1. 将判断标志 _enable_inactive_release 置为true
        _enable_inactive_release = true;
        //2. 如果当前定时销毁任务已经存在，那就刷新延迟一下即可
        if(_loop->HasTimer(_conn_id)){
            return _loop->TimerRefresh(_conn_id);
        }
        //3. 如果不存在定时销毁任务，则新增
        _loop->TimerAdd(_conn_id,sec,std::bind(&Connection::ShutdownInLoop,this));
    } 
    // 取消非活跃销毁
    void CancelInactiveReleaseInLoop(){
        _enable_inactive_release = false;
        if(_loop->HasTimer(_conn_id)){
            _loop->TimerCancel(_conn_id);
        }
    }        
    //切换协议---重置上下文以及阶段性处理函数
    void UpgradeInLoop(const Any &context, const ConnectedCallback &conn, const MessageCallback &msg,
                       const ClosedCallback &closed, const AnyEventCallback &event){
                        _context=context;
                        _connected_callback=conn;
                        _message_callback=msg;
                        _closed_callback=closed;
                        _event_callback=event;
                       }

public:
    Connection(EventLoop *loop, uint64_t conn_id, int sockfd)
        : _conn_id(conn_id), _sockfd(sockfd),_socket(_sockfd),_loop(loop), _statu(CONNECTING), _channel(new Channel(_loop,_sockfd))
    {
        _channel->SetReadCallback(std::bind(&Connection::HandleRead,this));
        _channel->SetWriteCallback(std::bind(&Connection::HandleWrite,this));
        _channel->SetErrorCallback(std::bind(&Connection::Shutdown,this));
        _channel->SetCloseCallback(std::bind(&Connection::Shutdown,this));
        _channel->SetEventCallback(std::bind(&Connection::HandleEvent,this));//任意事件回调都需要刷新时间
    }

    ~Connection(){
        DEBUG_LOG("RELEASE CONNECTION:%p:",this);
    }
    //获取连接ID
    uint64_t Id(){
        return _conn_id;
    }
    //获取管理的文件描述符
    int Fd(){
        return _sockfd;
    }
    //是否处于CONNECTED状态
    bool StatuIsCONNECTED(){
        return _statu == CONNECTED;
    }
    //设置上下文--连接建立完成时进行调用
    void SetContext(const Any &context){
        _context = context;
    }
    //获取上下文，返回的是指针
    Any* GetContext(){
        return &_context;
    }
    Connection* Get(){
        return this;
    }
    //上层设置的回调函数
    void SetConnectedCallback(const ConnectedCallback &conn){_connected_callback=conn;}
    void SetMessageCallback(const MessageCallback &msg) {_message_callback=msg;}
    void SetClosedCallback(const ClosedCallback &closed) {_closed_callback=closed;}
    void SetAnyEventCallback(const AnyEventCallback &event) {_event_callback=event;}
    void SetServerClosedCallback(const ClosedCallback &closed) {_server_close_callback=closed;}               
    // 连接建立就绪后，进行的一系列操作
    void Established()
    {
        _loop->RunInLoop((std::bind(&Connection::EstablishedInLoop, this)));
    }
    // 发送数据，将数据放到发送缓冲区，启动写事件监控
    void Send(char *data, size_t len)
    {
        //外界传入的data，可能是个临时的空间，我们现在只是把发送操作压入了任务池，有可能并没有被立即执行
        //因此有可能执行的时候，data指向的空间有可能已经被释放了。
        Buffer buf;
        buf.WriteAndPush(data,len);
        //_loop->RunInLoop(std::bind(&Connection::SendInLoop, this, data, len));
        //move完美转发减少拷贝
        _loop->RunInLoop(std::bind(&Connection::SendInLoop, this, std::move(buf)));

    }
    // 提供给组件使用者的关闭接口--并不实际关闭，需要判断有没有数据待处理
    void Shutdown()
    {
        _loop->RunInLoop(std::bind(&Connection::ShutdownInLoop, this));
    }
    //在test/client4的测试中，如果一个业务处理过久那么会导致其它活跃连接超时销毁，如果没有进行处理，直接进行销毁，后续在访问时会导致访问出错，
    //因此我们将销毁操作放到任务队列中最后进行处理
    void Release(){
        _loop->QueueInLoop(std::bind(&Connection::ReleaseInLoop, this));
    }
    // 启动非活跃销毁，并定义多长时间无通信就是非活跃，添加定时任务
    void EnableInactiveRelease(int sec)
    {
        _loop->RunInLoop(std::bind(&Connection::EnableInactiveReleaseInLoop, this, sec));
    }
    // 取消非活跃销毁
    void CancelInactiveRelease()
    {
        _loop->RunInLoop(std::bind(&Connection::CancelInactiveReleaseInLoop, this));
    }
    // 切换协议---重置上下文以及阶段性处理函数
    //注意点这个接口必须在EventLoop线程中立即执行
    //防备新的事件触发后，处理的时候，切换任务还没有被执行--会导致数据使用原协议处理了。
    void Upgrade(const Any &context, const ConnectedCallback &conn, const MessageCallback &msg,
                 const ClosedCallback &closed, const AnyEventCallback &event){
        _loop->RunInLoop(std::bind(&Connection::UpgradeInLoop, this,context, conn, msg,closed,event));
    }
};


class Acceptor{
private:
    Socket _lst_sock;//用于创建监听套接字
    int _listen_fd;
    EventLoop* _loop;//用于对监听套接字进行事件监控
    std::shared_ptr<Channel> _channel;//用于对监听套接字进行事件管理
    //连接到来时的回调函数
    using AcceptorCallback=std::function<void(int)>;
    AcceptorCallback _acceptor_cb;
public:
    //有新连接到来后的回调处理
    void HandleRead(){
        int newfd=accept(_listen_fd,nullptr,nullptr);
        if(newfd<0){
            ERR_LOG("ACCEPT FAIL:%s",strerror(newfd));
            std::cout<<"accept 错误"<<std::endl;
            return ;
        }
        //调用上层设置的新连接回调函数
        if(_acceptor_cb)
            _acceptor_cb(newfd);
    }
    int CreateServer(int port){
        if(_lst_sock.CreateServer(port)==false){
            DEBUG_LOG("CreateServer FAIL");
            exit(-1);
        }
        return _lst_sock.Fd();
    }
public:
    /*不能将启动读事件监控，放到构造函数中，必须在设置回调函数后，再去启动*/
    /*否则有可能造成启动监控后，立即有事件，处理的时候，回调函数还没设置：新连接得不到处理，且资源泄漏*/
    Acceptor(EventLoop* loop,int port)
    :_listen_fd(CreateServer(port))
    ,_loop(loop)
    ,_channel(new Channel(_loop,_listen_fd))
    {
        _channel->SetReadCallback(std::bind(&Acceptor::HandleRead,this));
        //_channel->EnableRead();错误
    }
    ~Acceptor(){
        _lst_sock.Close();
    }
    //设置新连接建立后的回调函数
    void SetAcceptorCallback(const AcceptorCallback& cb){
        _acceptor_cb=cb;
    }
    //确保有事件到来后，回调函数已经设置
    void Listen(){
        _channel->EnableRead();
    }
};


class TcpServer{
private:
    int _conn_id; //这是一个自动增长的连接ID
    std::unordered_map<int,PtrConnection> _conns;
    EventLoop _baseloop;
    Acceptor _acceptor;
    LoopThreadPool _pool;
    Any _context;
    int _sec;
    bool _enable_inactive_release;//是否启动了非活跃连接超时销毁的判断标志
    using ConnectedCallback = std::function<void(const PtrConnection &)>;               // 连接事件到来后的回调函数
    using MessageCallback = std::function<void(const PtrConnection &, Buffer *)>; // 数据到来后的回调函数
    using ClosedCallback = std::function<void(const PtrConnection &)>;            // 关闭事件到来后的回调函数
    using AnyEventCallback = std::function<void(const PtrConnection &)>;          // 任意事件到来后的回调函数
    using Functor = std::function<void()>;
    ConnectedCallback _connected_callback;
    MessageCallback _message_callback;
    ClosedCallback _closed_callback;
    AnyEventCallback _event_callback;

private:
    //对新连接的处理
    void NewConnection(int newfd){
        //设置新连接id
        _conn_id++;
        //设置一个PtrConnection（connection）对象管理新连接
        PtrConnection new_conn(new Connection(_pool.GetLoop(),_conn_id,newfd));
        //设置回调函数
        new_conn->SetMessageCallback(_message_callback);
        new_conn->SetClosedCallback(_closed_callback);
        new_conn->SetConnectedCallback(_connected_callback);
        new_conn->SetAnyEventCallback(_event_callback);
        new_conn->SetServerClosedCallback(std::bind(&TcpServer::RemoveConnection,this,std::placeholders::_1));
        //是否启动非活跃销毁
        if(_enable_inactive_release) new_conn->EnableInactiveRelease(_sec);
        //新连接的初始化操作
        new_conn->Established();
        //设置服务器对新连接的管理
        _conns.insert(std::make_pair(_conn_id,new_conn));
    }
    //服务负责对连接的最终释放
    void RemoveConnection(const PtrConnection& conn){
        _conns.erase(conn->Id());
    }

    //切换协议---重置上下文以及阶段性处理函数
    void UpgradeInLoop(const Any &context, const ConnectedCallback &conn, const MessageCallback &msg,
                       const ClosedCallback &closed, const AnyEventCallback &event){
                        _context=context;
                        _connected_callback=conn;
                        _message_callback=msg;
                        _closed_callback=closed;
                        _event_callback=event;
                       }

    void RunAfterInLoop(const Functor &task, int delay){
        _conn_id++;
        _baseloop.TimerAdd(_conn_id,delay,task);
    }
public:
    TcpServer(int port):_conn_id(0),_acceptor(&_baseloop,port),_pool(&_baseloop),_sec(0),_enable_inactive_release(false){
        //先设置读事件回调函数再启动读监控
        _acceptor.SetAcceptorCallback(std::bind(&TcpServer::NewConnection,this,std::placeholders::_1));
        _acceptor.Listen();
    }

    //设置回调函数
    void SetConnectedCallback(const ConnectedCallback &conn){_connected_callback=conn;}
    void SetMessageCallback(const MessageCallback &msg) {_message_callback=msg;}
    void SetClosedCallback(const ClosedCallback &closed) {_closed_callback=closed;}
    void SetAnyEventCallback(const AnyEventCallback &event) {_event_callback=event;} 
    //开启监听套接字监控
    void Start(){
        _pool.Create();
        _baseloop.Start();
    }
    //设置Loop线程池数量
    void SetThreadCount(int thread_count){_pool.SetThreadCount(thread_count);}
    //启动非活跃销毁
    void EnableInactiveRelease(int sec){
        _enable_inactive_release=true;
        _sec=sec;
    }
    //取消非活跃销毁
    void CancelRelease(){
        _enable_inactive_release=false;
    }
    //切换协议
    void Upgrade(const Any &context, const ConnectedCallback &conn, const MessageCallback &msg,
                 const ClosedCallback &closed, const AnyEventCallback &event){
        _baseloop.RunInLoop(std::bind(&TcpServer::UpgradeInLoop, this,context, conn, msg,closed,event));
    }
    //用于添加一个定时任务
    void RunAfter(const Functor &task, int delay) {
        _baseloop.RunInLoop(std::bind(&TcpServer::RunAfterInLoop, this, task, delay));
    }
};

//移除监控,不是关闭文件描述符
void Channel::Remove()
{ //_poller->RemoveEvent(this);
    _loop->RemoveEvent(this);
}
// 更新监控
void Channel::Update()
{ //_poller->UpdateEvent(this);
    _loop->UpdateEvent(this);
}

bool TimerWheel::TimerIsInLoop() { return _loop->IsInLoop(); }
void TimerWheel::TimerQueueInLoop(std::function<void()> fc) { _loop->QueueInLoop(fc);}

//服务器主动断开连接时，仍然保留客户端的进程。
//确保在整个程序运行期间，向已关闭的服务器写数据时不会导致程序崩溃，
class NetWork {
    public:
        NetWork() {
            DEBUG_LOG("SIGPIPE INIT");
            signal(SIGPIPE, SIG_IGN);
        }
};
static NetWork nw;